package it.canraid.control;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import android.content.Context;
import android.os.Environment;
import android.text.format.DateFormat;
import android.widget.Toast;

public class Logger extends Thread {
    private static final Level MAX_LEVEL = Level.ASSERT;
    private static volatile boolean run = false;
    private static boolean requestToRun = false;
    private static Logger logger = null;
    private static int queueLength = 0;
    private static char[] bufferOutput = new char[queueLength];
    private static Context mainView = null;
    private static File file = null;
    private static FileWriter filewriter = null;
    private static BufferedWriter fo = null;
    private static String fileName = "DebugCanraid.txt";

    private Logger() {
	file = new File(Environment.getExternalStorageDirectory() + File.separator + fileName);
	try {
	    filewriter = new FileWriter(file);
	    fo = new BufferedWriter(filewriter);
	} catch (IOException e) {
	    close();
	    if (mainView != null)
		Toast.makeText(mainView, "Exception opening LOG FILE. Debugger switched off.", Toast.LENGTH_LONG).show();
	} finally {
	}
    }

    public static void startLog(Context mainView, String fileName) {
	Logger.mainView = mainView;
	if (fileName != null && fileName.length() > 0)
	    Logger.fileName = fileName;

	if (logger == null) {
	    logger = new Logger();
	    logger.setName("LOGGER");
	    logger.setDaemon(false);
	    logger.start();
	    if (Logger.mainView != null)
		Toast.makeText(mainView, "Log Started.", Toast.LENGTH_SHORT).show();
	}
    }

    public static void close() {
	stopLog();
	while (run) {
	    try {
		Thread.sleep(1000);
	    } catch (Exception e) {
	    }
	}
	try {
	    if (fo != null) {
		fo.flush();
		fo.close();
		filewriter.close();
	    }
	} catch (IOException e) {
	} finally {
	    fo = null;
	    logger = null;
	    filewriter = null;
	    file = null;
	}
    }

    public static boolean setLog(Object obj, Level level, String text) {

	if (!run)
	    return false;

	if (Level.whoIsMax(MAX_LEVEL, level) > 0)
	    return false;

	long time = System.currentTimeMillis();
	String ddMMyyyyHHmm = DateFormat.format("dd-MM-yyyy hh:mm", time).toString();
	String textInFile = time + ", " + level + ", " + ddMMyyyyHHmm + ", " + obj.getClass().getName() + ", " + text + System.getProperty("line.separator");

	byte[] textInFileToByte = textInFile.getBytes();
	char[] textInFileToChar = new char[textInFileToByte.length];
	for (int i = 0; i < textInFileToChar.length; i++)
	    textInFileToChar[i] = (char) textInFileToByte[i];

	synchronized (bufferOutput) {
	    // Impilatura
	    char[] newBuffer = new char[bufferOutput.length + textInFileToChar.length];
	    System.arraycopy(bufferOutput, 0, newBuffer, 0, bufferOutput.length);
	    System.arraycopy(textInFileToChar, 0, newBuffer, bufferOutput.length, textInFileToChar.length);
	    bufferOutput = newBuffer;
	    queueLength = bufferOutput.length;
	}

	return true;
    }

    public void run() {
	run = true;
	int delta = 0;
	requestToRun = true;
	while (requestToRun) {
	    try {
		Thread.sleep(delta + 2000);
		delta = 0;
		fo.write(__getCopyBufferOutput());
		fo.flush();
	    } catch (Exception e) {
		Toast.makeText(mainView, "Exception! LOG FILE. Error:" + e.getMessage(), Toast.LENGTH_LONG).show();
		delta = 5000;
	    } finally {
	    }
	}
	run = false;
	close();
    }

    public static void stopLog() {
	requestToRun = false;
    }

    private static char[] __getCopyBufferOutput() {
	char[] newBuffer = null;
	synchronized (bufferOutput) {
	    newBuffer = new char[bufferOutput.length];
	    System.arraycopy(bufferOutput, 0, newBuffer, 0, bufferOutput.length);
	    bufferOutput = new char[0];
	    queueLength = 0;
	}
	return newBuffer;
    }

}
